/*=============================================================================

  APPLICATION MANAGER MODULE

  FILE: IOmgr.cpp
  
  DESCRIPTION

    Manager Module Definition

  EXTERNALIZED FUNCTIONS

    
  Copyright (c) DaeSung Engineering Inc. All rights reserved.

=============================================================================*/
/*=============================================================================

                             EDIT HISTORY

  ---------  -------  -------------------------------------------------------
    when       who     what, where, why
  ---------  -------  -------------------------------------------------------
   06/28/03   nso4th   Version 0.1

=============================================================================*/

/*=============================================================================
  HEADER INCLUSION
=============================================================================*/
#include "IOmgr_MOD.h"

/*=============================================================================
  CONSTANT IMPLEMENTATION
=============================================================================*/
#define MON_SYNCWAIT_TIME			(200) // 1 sec
#define IO_CONNREG_TIME_DEF		(60000) // 60 sec.

/*=============================================================================
  LOCALIZED FUNCTION DEFINITION
=============================================================================*/

/*=============================================================================
  UI MONITORING DEFINITION
=============================================================================*/
void IOmgr::MON_Alloc(void)
{
	m_monSync = Sync_Alloc();
	m_monLock = TRUE;
	m_reqLock = FALSE;
	m_reqWait = FALSE;

	m_monCnt = 0;

	m_connDev = m_connReg = FALSE;
	m_connTime = IO_CONNREG_TIME_DEF;

	// OP-SWITCH
	m_switchReg = IOmgr_BASE_E;
	m_switchCount = 0;
}

void IOmgr::MON_Free(void)
{
	if(m_monSync)
	{
		Sync_Free(m_monSync);
		m_monSync = NULL;
	}
}

void IOmgr::MON_STATE(void)
{
	HIO			*io = (HIO*)ObjList_Get(HIO_DEV);
	
	if(io == NULL)
	{
		return;
	}

	// Have to be prcessed in State Tick time

	if(m_monCnt%10 == 0)
	{
		MON_DEVICE();
	}
	MON_IOPOLL(m_monCnt);

	m_monCnt++;
}

void IOmgr::MON_LOCK(boolean lock)
{
	HIO			*io = (HIO*)ObjList_Get(HIO_DEV);
	
	if(io == NULL)
	{
		return;
	}

	m_reqWait = TRUE;
	m_reqLock = lock;

	Sync_Set(m_monSync, FALSE); 
	Task_PutSignal(m_pTask, TASK_SIG_SYNC);
	if(Sync_Wait(m_monSync, MON_SYNCWAIT_TIME) == FALSE)
	{
//		DBGPRINT("[IOmgr] MON_LOCK.....time-out\n");
		m_reqWait = FALSE;
		m_reqLock = FALSE;
		m_monLock = TRUE;
	}

	if(lock == FALSE)
	{
		MON_DEVICE(); // Update
	}
	else
	{
		// Dergister timer !!
		Timer_Dereg(IOmgr_TM_TRY_ID);
		m_connReg = FALSE;
	}
}

void IOmgr::MON_DEVICE(void)
{
	HIO			*io = (HIO*)ObjList_Get(HIO_DEV);
	dword		prev_state, new_state;
	boolean		dev_conn =FALSE;

	if(io == NULL)
	{
		State_Major(IOmgr_IDL_S);
		return;
	}

	prev_state = State_MajCurrent();
	new_state = IOmgr_IDL_S;

	if(io->IsDeviceAvail())
	{
		new_state = IOmgr_CONN_S;
		dev_conn = TRUE;
	}
	else
	{
		new_state = IOmgr_ERR_S;
	}

	if(dev_conn == TRUE)
	{
		if(prev_state == IOmgr_TRY_S)
		{
			Timer_Dereg(IOmgr_TM_TRY_ID);
		}
		// Connection OK.
		m_connDev = dev_conn;
	}
	else
	{
		if(new_state != IOmgr_TRY_S)
		{
			// Try  connect !!!!
			if(m_connReg == FALSE)
			{
//				DBGPRINT("[IOmgr] Register connection trying timer in %d sec.\n", m_connTime/1000);
				Timer_Dereg(IOmgr_TM_TRY_ID);
				Timer_Reg(IOmgr_TM_TRY_ID, m_connTime);
				m_connReg = TRUE;
			}
			new_state = IOmgr_TRY_S;
		}
	}
	if(new_state != prev_state)
	{
		if(new_state == IOmgr_CONN_S)
		{
			MON_IOUPDATE(TRUE);
		}
		State_Major(new_state);
	}
}

void IOmgr::MON_IOPOLL(int32 cnt)
{
	if(m_connDev == FALSE)
		return;

	if(cnt%10 == 0)
	{
		MON_IOPOLL_OUTPUT(cnt);
	}
	MON_IOPOLL_INPUT(cnt);
}

void IOmgr::MON_IOUPDATE(boolean dev_reset)
{
	if(dev_reset == TRUE)
	{
		MON_IOPOLL_INPUT(-1);
		MON_IOPOLL_OUTPUT(-1);
	}
	else
	{
		MON_IOPOLL_INPUT(0);
		MON_IOPOLL_OUTPUT(0);
	}
}

void IOmgr::MON_IOPOLL_INPUT(int32 cnt)
{
	HIO				*io = (HIO*)ObjList_Get(HIO_DEV);
	int32			inNum, outNum;
	dword			modNum, j;
	static dword		prevIn[4], curIn[4];
	
	if(m_connDev == FALSE)
		return;

	if(io->GetIOInfo(&inNum, &outNum) == FALSE)
		return;

	if(inNum > 0)
	{
		modNum = (dword)(inNum / 32) + 1;
		modNum = MIN(modNum, 4);
		for(j=0; j<modNum; j++)
		{
			if(io->Input32Ex(j, &curIn[j]) == FALSE)
				continue;

			if(cnt < 0)
			{
				prevIn[j] = (dword)(~curIn[j]);
			}
			if(prevIn[j] != curIn[j])
			{
				Event_Handler(IO_MGR, (IOmgr_IN_MOD0_E+j), curIn[j], prevIn[j]);
				prevIn[j] = curIn[j];
			}
		}
	}
}

void IOmgr::MON_IOPOLL_OUTPUT(int32 cnt)
{
	HIO					*io = (HIO*)ObjList_Get(HIO_DEV);
	int32				inNum, outNum;
	dword				modNum, j;
	static dword		prevOut[4], curOut[4];
	
	if(m_connDev == FALSE)
		return;

	if(io->GetIOInfo(&inNum, &outNum) == FALSE)
		return;

	if(outNum > 0)
	{
		modNum = (dword)(outNum / 32) + 1;
		modNum = MIN(modNum, 4);
		for(j=0; j<modNum; j++)
		{
			if(io->IsOutput32Ex(j, &curOut[j]) == FALSE)
				continue;

			if(cnt < 0)
			{
				prevOut[j] = (dword)(~curOut[j]);
			}
			if(prevOut[j] != curOut[j])
			{
				Event_Handler(IO_MGR, (IOmgr_OUT_MOD0_E+j), curOut[j], prevOut[j]);
				prevOut[j] = curOut[j];
			}
		}
	}
}


/*--- END OF IOmgr_MON.CPP ---*/
